#include <jni.h>
#include <string>
#include <pthread.h>
#include "MyLog.h"

extern "C" {

JNIEXPORT jstring JNICALL Java_com_example_testjni_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

JNIEXPORT void JNICALL Java_com_example_testjni_MainActivity_testFirst(JNIEnv *env,
                                                                       jobject instance, jint i,
                                                                       jstring j) {
    const char* str = env->GetStringUTFChars(j, 0); //没有这一句会乱码
    LOGE("%d, %s", i, str);
}

JNIEXPORT void JNICALL
Java_com_example_testjni_MainActivity_testArray(JNIEnv *env, jobject thiz, jintArray i,
                                                jobjectArray j) {
    jint * j_i = env->GetIntArrayElements(i, NULL);// 第二个参数一般为null
    //C调用方法： jint * j_i = (*env)->GetIntArrayElements(i, null);
    jint len = env->GetArrayLength(i);
    for(int a = 0; a < len; a++) {
        LOGE("%d", j_i[a]);
        LOGE("%d", *(j_i + a));
        //测试mode，修改值
        *(j_i + a) = 100;
    }

    //参数3：mode
    //0: 刷新java数组，并释放c/C+数组
    //1:= JNI_COMMIT 只刷新Java数组
    //2:=JNI_ABORT 只释放
    env->ReleaseIntArrayElements(i, j_i, 0);//对象都要释放


    jint strLen = env->GetArrayLength(j);
    for(int b = 0; b < strLen; b++) {
        jstring str = static_cast<jstring >(env->GetObjectArrayElement(j, b));
        const char* cStr = env->GetStringUTFChars(str, 0);
        LOGE("%s", cStr);
        env->ReleaseStringUTFChars(str, cStr);

    }
}

JNIEXPORT void JNICALL
Java_com_example_testjni_MainActivity_testObject(JNIEnv *env, jobject thiz, jobject test_bean,
                                                 jstring str) {
    const char* pStr = env->GetStringUTFChars(str, 0);
    LOGE("%s", pStr);

    //反射调用java方法
    //1,获取java对应的class对象
    jclass beanCls = env->GetObjectClass(test_bean);
    //或者：jclass beanCls = env->FindClass("com/example/testjni/TestBean");
    //2,找到要调用的方法
    //参数3：签名
    jmethodID getUserName = env->GetMethodID(beanCls, "getUserName", "()Ljava/lang/String;");
    jmethodID setUserName = env->GetMethodID(beanCls, "setUserName", "(Ljava/lang/String;)V");
    jmethodID staInt = env->GetStaticMethodID(beanCls, "staInt", "(I)I");
    jmethodID staBean = env->GetStaticMethodID(beanCls, "staBean", "(Lcom/example/testjni/TestBean;)Lcom/example/testjni/TestBean;");
    //3，调用
    jstring jUserName = static_cast<jstring>(env->CallObjectMethod(test_bean, getUserName));
    const char* pUserName = env->GetStringUTFChars(jUserName, 0);
    LOGE("%s", pUserName);


    //创建java字符串
    jstring jName = env->NewStringUTF("我们");
    env->CallVoidMethod(test_bean, setUserName, jName);

    jint jstaInt = env->CallStaticIntMethod(beanCls, staInt, 10);
    LOGE("%d", jstaInt);

    //反射创建对象，构造函数
    //a、获得类的构造函数
    jmethodID constuctId = env->GetMethodID(beanCls, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");
    jstring jbean2Name = env->NewStringUTF("甘雅琴");
    jstring jbean2Password = env->NewStringUTF("0510");
    jobject bean2 = env->NewObject(beanCls, constuctId, jbean2Name, jbean2Password);
    jobject rebean2 = env->CallStaticObjectMethod(beanCls, staBean, bean2);

    //返回对象打印值
    jstring jUserName2 = static_cast<jstring>(env->CallObjectMethod(rebean2, getUserName));
    const char* pUserName2 = env->GetStringUTFChars(jUserName2, 0);
    LOGE("%s", pUserName2);


    jfieldID fieldId = env->GetFieldID(beanCls, "age", "I");
    jint jfield = env->GetIntField(test_bean, fieldId);
    LOGE("%d", jfield);
    env->SetIntField(test_bean, fieldId, 31);
    jint jfield2 = env->GetIntField(test_bean, fieldId);
    LOGE("%d", jfield2);

    //释放New出来的，也可以不写，退出方法会释放
    env->DeleteLocalRef(jName);
    env->DeleteLocalRef(jbean2Name);
    env->DeleteLocalRef(jbean2Password);
    env->DeleteLocalRef(bean2);
    env->ReleaseStringUTFChars(jUserName, pUserName);
    env->ReleaseStringUTFChars(jUserName2, pUserName2);
    env->ReleaseStringUTFChars(str, pStr);
}

}

